package cn.scy.util.xiamdx;

import javax.crypto.Cipher;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.SecureRandom;
import java.util.Base64;

public class AESGCMUtil {

    private static final String AES_ALGORITHM = "AES";
    private static final String AES_GCM_NO_PADDING = "AES/GCM/NoPadding";
    private static final int GCM_TAG_LENGTH = 128;
    private static final int IV_LENGTH = 12;

    private static byte[] keyFromString(String key) throws Exception {
        MessageDigest md = MessageDigest.getInstance("MD5");
        return md.digest(key.getBytes(StandardCharsets.UTF_8));
    }

    public static String encrypt(String plainText, String key) throws Exception {
        byte[] keyBytes = keyFromString(key);

        byte[] iv = new byte[IV_LENGTH];
        new SecureRandom().nextBytes(iv);

        SecretKeySpec keySpec = new SecretKeySpec(keyBytes, AES_ALGORITHM);
        GCMParameterSpec gcmSpec = new GCMParameterSpec(GCM_TAG_LENGTH, iv);

        Cipher cipher = Cipher.getInstance(AES_GCM_NO_PADDING);
        cipher.init(Cipher.ENCRYPT_MODE, keySpec, gcmSpec);

        byte[] cipherText = cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8));

        byte[] combined = new byte[IV_LENGTH + cipherText.length];
        System.arraycopy(iv, 0, combined, 0, IV_LENGTH);
        System.arraycopy(cipherText, 0, combined, IV_LENGTH, cipherText.length);

        return Base64.getEncoder().encodeToString(combined);
    }

    public static String decrypt(String encryptedBase64, String key) throws Exception {
        byte[] keyBytes = keyFromString(key);
        byte[] allBytes = Base64.getDecoder().decode(encryptedBase64);

        byte[] iv = new byte[IV_LENGTH];
        byte[] cipherText = new byte[allBytes.length - IV_LENGTH];
        System.arraycopy(allBytes, 0, iv, 0, IV_LENGTH);
        System.arraycopy(allBytes, IV_LENGTH, cipherText, 0, cipherText.length);

        SecretKeySpec keySpec = new SecretKeySpec(keyBytes, AES_ALGORITHM);
        GCMParameterSpec gcmSpec = new GCMParameterSpec(GCM_TAG_LENGTH, iv);

        Cipher cipher = Cipher.getInstance(AES_GCM_NO_PADDING);
        cipher.init(Cipher.DECRYPT_MODE, keySpec, gcmSpec);

        byte[] plainText = cipher.doFinal(cipherText);
        return new String(plainText, StandardCharsets.UTF_8);
    }

    public static void main(String[] args) throws Exception {
        String key = "a023d95b2fd66954aa0dc398";
        String text = "13049961398";
        String encrypted1 = "WKaa4bYVz4PD9Kof643xcBdv6fubORCbI4ZtMqt2Vz4ua6d/HvBK";

        String encrypted = encrypt(text, key);
        String decrypted = decrypt(encrypted, key);

        System.out.println("原文: " + text);
        System.out.println("加密串（IV+密文 Base64）: " + encrypted);
        System.out.println("解密后: " + decrypted);

        String decrypted1 = decrypt(encrypted1, key);
        System.out.println("解密后: " + decrypted1);
    }
}
